﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using RebEngine.Managers;
using RebEngine.GameComponents;
using Microsoft.Xna.Framework.Input;
using SysWinForms = System.Windows.Forms;
using System.Xml;
using RebellionII.GameObjects;
using System.Collections.Generic;

namespace RebEngine
{
    public partial class RebEngine : Game
    {
        // basic properties
        protected static int gameWidth, gameHeight;
        private static float aspectRatio = 1.0f;
        private static Color _backgroundColor = Color.Purple;
        private static string _windowTitle = "";
        private bool _isAppActive = false;
        private static bool _applyDeviceChanges = false;
        public static GameSettings Settings { get; set; }

        public static Color EmpireColor { get; set; }
        public static Color AllianceColor { get; set; }
        public static Color HuttsColor { get; set; }
        public static Color SmugglersColor { get; set; }
        public static Color DefaultColor { get; set; }

        #region Manager Null Creation
        // The different managers used in the engine.
        protected static GraphicsDeviceManager _graphicsDeviceManager = null;
        protected static ContentManager _contentManager = null;
        private static TextureManager _textureManager = null;
        private static ScreenManager _screenManager = null;
        private static SceneGraphManager _sceneGraphManager = null;
        private static ModelManager _modelManager = null;
        private static InputManager _inputManager = null;
        private static SoundManager _soundManager = null;
        private static MusicManager _musicManager = null;
        private static NetServerManager _networkManager = null;
        private static LogManager _logManager = null;
        private static Tick _tick = null;
        private static NetClientManager _netClientManager = null;
        private static FpsCounter _fpsCounter = null;
        #endregion

        #region Accessor Functions
        public static int Width
        {
            get { return gameWidth; }
        }
        public static int Height
        {
            get { return gameHeight; }
        }
        public static float AspectRatio
        {
            get { return aspectRatio; }
        }
        public static Color BackgroundColor
        {
            get { return _backgroundColor; }
            set { _backgroundColor = value; }
        }
        public static string WindowTitle
        {
            get { return _windowTitle; }
        }
        public bool IsAppActive
        {
            get { return _isAppActive; }
            set { _isAppActive = value; }
        }
        public static GraphicsDevice Device
        {
            get { return _graphicsDeviceManager.GraphicsDevice; }
        }
        public static GraphicsDeviceManager GDManager
        {
            get { return _graphicsDeviceManager; }
        }
        public static ContentManager ContentManager
        {
            get { return _contentManager; }
        }
        #endregion

        protected RebEngine(string windowsTitle)
        {
            Settings = new GameSettings();
            Settings.ReadXMLintoOptions();

            EmpireColor = Color.LimeGreen;
            AllianceColor = Color.Red;
            HuttsColor = Color.Goldenrod;
            SmugglersColor = Color.BlueViolet;
            DefaultColor = Color.RoyalBlue;

            _graphicsDeviceManager = new GraphicsDeviceManager(this);
            IsMouseVisible = true;

            _graphicsDeviceManager.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(GraphicsDeviceManager_PreparingDeviceSettings);
            ApplyResolutionChange(EngineManager.Settings.Width, EngineManager.Settings.Height);
            this.IsFixedTimeStep = false;

            GDManager.DeviceCreated += new EventHandler<EventArgs>(GDManager_DeviceCreated);
            #region Manager Creation
            // Here we create all the managers and add them as components.
            
            #endregion

            _graphicsDeviceManager.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(_graphicsDeviceManager_PreparingDeviceSettings);

            ApplyResolutionChange(EngineManager.Settings.Width, EngineManager.Settings.Height);
            GDManager.SynchronizeWithVerticalRetrace = false;
        }

        void GDManager_DeviceCreated(object sender, EventArgs e)
        {
            _contentManager = new ContentManager(this.Services);
            _logManager = new LogManager(this);
            _textureManager = new TextureManager(this);

            _sceneGraphManager = new SceneGraphManager(this);
            _modelManager = new ModelManager(this);
            _soundManager = new SoundManager(this);
            _networkManager = new NetServerManager(this);
            _musicManager = new MusicManager(this);
            _inputManager = new InputManager(this);
            _screenManager = new ScreenManager(this);
            _tick = new Tick(this);
            _netClientManager = new NetClientManager(this);
            _fpsCounter = new FpsCounter(this);

            Components.Add(_logManager);
            Components.Add(_textureManager);
            Components.Add(_modelManager);
            Components.Add(_sceneGraphManager);
            Components.Add(_soundManager);
            Components.Add(_networkManager);
            Components.Add(_musicManager);
            Components.Add(_tick);
            Components.Add(_inputManager);
            Components.Add(_screenManager);
            Components.Add(_netClientManager);
            Components.Add(_fpsCounter);

            
        }

        

        void _graphicsDeviceManager_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            e.GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage = RenderTargetUsage.PreserveContents;
        }

        protected RebEngine()
            : this("Game")
        {
            
        }

        protected override void Initialize()
        {
            SceneGraphManager.DebugDrawing = Settings.DebugMode;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
        }
 
        protected override void Update(GameTime gameTime)
        {
            Timer.Update(gameTime);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            // Apply device changes
            if (_applyDeviceChanges)
            {
                _graphicsDeviceManager.ApplyChanges();
                _applyDeviceChanges = false;
                //_inputManager.ReadyManager();
            }
        }

        #region Other Functions/Ignore these

        protected override void OnActivated(object sender, EventArgs args)
        {
            base.OnActivated(sender, args);
            IsAppActive = true;
        }

        protected override void OnDeactivated(object sender, EventArgs args)
        {
            base.OnDeactivated(sender, args);
            IsAppActive = false;
        }

        void GraphicsDeviceManager_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {

        }

        public static void CheckOptionsAndPSVersion()
        {
            if (Device == null)
            {
                throw new InvalidOperationException("Graphics Device is not created yet!");
            }
        }

        public static void ApplyResolutionChange(int width, int height)
        {
            int resolutionWidth = width;
            int resolutionHeight = height;
            gameHeight = height;
            gameWidth = width;
            if (resolutionWidth <= 0 || resolutionWidth <= 0)
            {
                resolutionWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
                resolutionHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
            }


            _graphicsDeviceManager.PreferredBackBufferWidth = resolutionWidth;
            _graphicsDeviceManager.PreferredBackBufferHeight = resolutionHeight;
            _graphicsDeviceManager.IsFullScreen = Settings.IsFullScreen;

            _applyDeviceChanges = true;
        }
        #endregion
    }
}